package com.jixiang.user.service.impl;

import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jixiang.apiFeignt.clients.AdrClient;
import com.jixiang.model.common.dtos.ResponseResult;
import com.jixiang.model.common.enums.AppHttpCodeEnum;
import com.jixiang.model.user.entity.UsUser;
import com.jixiang.user.dao.UsAdressDao;
import com.jixiang.model.user.entity.UsAdress;
import com.jixiang.user.service.UsAdressService;
import com.jixiang.utils.thread.UserThread;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static com.jixiang.common.constants.RedisConstants.*;

/**
 * (UsAdress)表服务实现类
 *
 * @author makejava
 * @since 2023-11-04 23:20:16
 */
@Service("usAdressService")
public class UsAdressServiceImpl extends ServiceImpl<UsAdressDao, UsAdress> implements UsAdressService {
    
    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    RedissonClient redissonClient;

    @Autowired
    AdrClient adrClient;
    @Override
    public ResponseResult appGetAddress() {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        List<UsAdress> usAdresses = renewUserAdr(user.getId());
        return ResponseResult.okResult(usAdresses);
    }

    @Override
    public ResponseResult appUpdateAddress(String adrId) {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        List<UsAdress> list = query().eq("user_id", user.getId()).list();
        list.forEach(item -> {
            item.setIsDefault(0);
            if(item.getId() == Long.valueOf(adrId)){
                item.setIsDefault(1);
            }
            boolean b = updateById(item);
        });
        stringRedisTemplate.delete(REDIS_PREX_ADR + user.getId().toString());
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<UsAdress> usAdresses = renewUserAdr(user.getId());
                if(!usAdresses.isEmpty()){
                    System.out.println("appUpdateAddress->succeed");
                }
            }
        },"appUpdateAddressRenewUserAdr").start();
        return ResponseResult.okResult("修改成功");
    }

    @Override
    public ResponseResult appAddAdress(UsAdress usAdress) {
        UsUser user = UserThread.getUser();
        if(user == null){
            return  ResponseResult.errorResult(AppHttpCodeEnum.TOKEN_EXPIRE);
        }
        stringRedisTemplate.delete(REDIS_PREX_ADR + user.getId().toString());
        String pro = adrClient.serverGetAdrBYId(usAdress.getProvinceCode());
        String city = adrClient.serverGetAdrBYId(usAdress.getCityCode());
        String county = adrClient.serverGetAdrBYId(usAdress.getCountyCode());
        usAdress.setFullLocation(pro+city+county);
        usAdress.setUserId(user.getId());
        save(usAdress);
        stringRedisTemplate.delete(REDIS_PREX_ADR + user.getId().toString());
        new Thread(new Runnable() {
            @Override
            public void run() {
                List<UsAdress> usAdresses = renewUserAdr(user.getId());
                if(!usAdresses.isEmpty()){
                    System.out.println("appUpdateAddress->succeed");
                }
            }
        },"appUpdateAddressRenewUserAdr").start();
        return ResponseResult.okResult("添加成功");
    }

    @Override
    public ResponseResult wxAppGetwxUserAdrData() {
        Long userId = UserThread.getUser().getId();
        LinkedList<UsAdress> list = new LinkedList<>();
        List<UsAdress> isDefaultList = query().eq("user_id", userId).eq("is_default", 1).list();
        if(!isDefaultList.isEmpty()){
            list.addAll(isDefaultList);
        }
        List<UsAdress> notDefaultList = query().eq("user_id", userId).eq("is_default", 0).list();
        if(!notDefaultList.isEmpty()){
            list.addAll(notDefaultList);
        }
        return ResponseResult.okResult(list);
    }

    @Override
    public ResponseResult wxAppAddwxUserAdrData(UsAdress usAdress) {
//        if(StrUtil.isBlank(usAdress.getIsDefault().toString())){
//            usAdress.setIsDefault(0);
//        }
        Long userId = UserThread.getUser().getId();
        usAdress.setUserId(userId);
        if(usAdress.getIsDefault() == 1){
            UpdateWrapper<UsAdress> UsAdressWrapper = new UpdateWrapper<>();
            UsAdressWrapper.eq("user_id",userId);
            UsAdress usAdress1 = new UsAdress();
            usAdress1.setIsDefault(0);
            boolean update = update(usAdress1, UsAdressWrapper);
        }
        if(usAdress.getId()==null){
            boolean save = save(usAdress);
        }else {
            updateById(usAdress);
        }

        return ResponseResult.okResult("操作成功");
    }

    public List<UsAdress> renewUserAdr (Long id) {
        String redisData = stringRedisTemplate.opsForValue().get(REDIS_PREX_ADR + id.toString());
        List<UsAdress> returnlist = new LinkedList<UsAdress>();
        if(StrUtil.isNotBlank(redisData)){
            List<UsAdress> list = JSONUtil.toList(redisData, UsAdress.class);
            returnlist = list;
        }
        if(redisData!=null){
            return returnlist;
        }
        RLock lock = redissonClient.getLock(REDIS_LOCK_ADR + id.toString());
        try {
            boolean tryLock = lock.tryLock(500, TimeUnit.MILLISECONDS);
            if(!tryLock){
                renewUserAdr(id);
            }
            List<UsAdress> list = query().eq("user_id", id).orderByDesc("create_time").list();
            if(list == null || list.isEmpty()){
                return returnlist;
            }
            JSONArray objects = JSONUtil.parseArray(list);
            stringRedisTemplate.opsForValue().set(REDIS_PREX_ADR+id.toString(),objects.toString(),REDIS_EXPIRE_ADR,TimeUnit.HOURS);
            returnlist = list;
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        } finally {
            lock.unlock();
        }
        return returnlist;
    }


}

